import json
import os
import re

from celery import current_app
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponse
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt

from celery.utils.serialization import jsonify
from django import http
from django.contrib.auth import login, logout

from django.db import DatabaseError

from apps.case.models import Case
from apps.news.models import Collection, News, Category
from apps.user.models import User, Fans
from django.shortcuts import render, redirect

from django.views import View
from django_redis import get_redis_connection

from libs.city import citys
from libs.qiniuyun.uploadpic import storage
from luntan_mall.settings import BASE_DIR
from utils.email import Email


@method_decorator(csrf_exempt, name="dispatch")
class RegisterView(View):
    """用户注册"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """

        return render(request, 'user/reg.html')

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        print(data)
        mobile = data.get("email")
        sms_code = data.get("sms_code")
        password = data.get("password")
        password2 = data.get("password2")
        username = data.get("username")
        print(sms_code, mobile, password, password2, username)
        if not all([username, password, password2, mobile, sms_code]):
            print("*" * 30)
            return http.HttpResponseBadRequest('缺少必传参数')
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入5-20个字符的用户名')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
        # 判断两次密码是否一致
        if password != password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')
        # return http.HttpResponse("ok")
        # if len(sms_code) != 6:
        #     return http.HttpResponseBadRequest('你输入的验证码有误')
        print("123")
        redis_conn = get_redis_connection('code')
        sms_code_saved = redis_conn.get('sms_%s' % mobile)
        if sms_code_saved is None:
            return render(request, 'user/reg.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_saved.decode():
            return render(request, 'user/reg.html', {'sms_code_errmsg': '输入短信验证码有误'})
        # 保存注册数据
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request, 'user/reg.html', {'register_errmsg': '注册失败'})
        login(request, user)
        ret = {
            "errno": 0,
            "errmsg": "注册成功"
        }
        return http.HttpResponse(json.dumps(ret), content_type="application/json")
        # response = redirect(reverse('index:index'))
        # response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        # return response


@method_decorator(csrf_exempt, name="dispatch")
class LoginView(View):
    def get(self, request):
        return render(request, "user/login.html")

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        mobile = data.get("phone")
        vercode = data.get("vercode")
        password = data.get("password")
        uuid = data.get("uuid")
        if not all([uuid, vercode, password, mobile]):
            return http.JsonResponse({'code': "7410", 'errmsg': '数据异常，登录失败'})
        redis_conn = get_redis_connection('code')
        t_f = redis_conn.get("img_%s" % uuid)
        if not t_f:
            return http.JsonResponse({'code': "7410", 'errmsg': '验证码错误'})
        if t_f.decode().lower() != vercode.lower():
            return http.JsonResponse({'code': "200", 'errmsg': '验证码错误'})
        if re.search(r'^\d{11}$', mobile):
            # 手机号登录
            user = User.objects.filter(mobile=mobile)
            if not user:
                return http.JsonResponse({'code': "200", 'errmsg': '手机号不存在'})
        else:
            # 邮箱登录
            user = User.objects.filter(email=mobile)
            if not user:
                return http.JsonResponse({'code': "200", 'errmsg': '邮箱不存在'})
        if not user[0].check_password(password):
            return http.JsonResponse({'code': "200", 'errmsg': '账号或者密码错误'})
        login(request, user[0])
        return http.JsonResponse({'code': "0", 'errmsg': '登录成功'})


class LogoutView(LoginRequiredMixin, View):
    """退出登录"""

    def get(self, request):
        """实现了退出了功能"""
        # 清除session
        logout(request)
        # 退出登录，重新定向到主页
        response = redirect(reverse('index:index'))
        response.delete_cookie("username")
        return response


class UserIndexView(LoginRequiredMixin, View):
    def get(self, request):
        context = {
            'user': request.user
        }
        return render(request, "user/index.html", context=context)


class UserIndexActivateView(View):
    def get(self, request):
        email = request.user.email
        # 4.发送验证邮箱

        ret = Email.send_email(request, email)
        print(">>>>>>>>发送邮件>>>>>>", ret)
        context = {
            'user': request.user
        }

        return render(request, "user/activate.html", context=context)


@method_decorator(csrf_exempt, name="dispatch")
class UserSetView(LoginRequiredMixin, View):
    def get(self, request):
        context = {
            'user': request.user
        }
        return render(request, "user/set.html", context=context)

    def post(self, request):
        response = redirect(reverse('user:userset'))
        return response


@method_decorator(csrf_exempt, name="dispatch")
class UserSetsView(LoginRequiredMixin, View):
    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        # email: "1060377319@qq.com"
        # username: "zhang15"
        # sign: ""
        # gender: "0"
        email = data.get("email")
        username = data.get("username")
        sign = data.get("sign")
        city = data.get("city")
        gender = data.get("gender")
        print(email, username, sign, gender, city)
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            ret = {"status": 201, "msg": "用户名格式错误"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        if not re.search("\w{5,20}@(163|qq|126)\.com$", email):
            ret = {"status": 202, "msg": "邮箱格式错误"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        if city not in citys:
            ret = {"status": 203, "msg": "城市格式错误例如:北京市"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        if sign == "":
            sign = request.user.signature

        users = request.user
        # mobile = users.mobile
        # user = User.objects.get(mobile=mobile)
        try:
            request.user.email = email
            request.user.gender = gender
            request.user.city = city
            request.user.username = username
            request.user.signature = sign
            request.user.save()
        except Exception as e:
            ret = {"status": 204, "msg": "修改失败"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        ret = {"status": 0, "msg": "修改成功"}
        return http.HttpResponse(json.dumps(ret), content_type="application/json")


class UserMessage(View):
    def get(self, request):
        context = {
            'user': request.user
        }
        return render(request, "user/message.html", context=context)


@method_decorator(csrf_exempt, name="dispatch")
class UserRepassView(LoginRequiredMixin, View):
    def post(self, request):
        # print("123")
        data = json.loads(request.body.decode("utf-8"))
        old_password = data.get("old_pwd")
        password = data.get("pwd1")
        password2 = data.get("pwd2")
        # print(old_password, "*", password, password2)
        if not all([old_password, password, password2]):
            ret = {"status": 101, "msg": "缺少参数"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            ret = {"status": 102, "msg": "密码不是6-16个字符"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        # 判断两次密码是否一致
        if password != password2:
            ret = {"status": 103, "msg": "两次密码不一致"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        users = request.user
        mobile = users.mobile
        user = User.objects.get(mobile=mobile)
        print(user)
        if not user.check_password(old_password):
            ret = {"status": 104, "msg": "旧密码错误"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        try:
            request.user.set_password(password)
            request.user.save()
        except Exception as e:
            ret = {"status": 105, "msg": "修改失败"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        ret = {"status": 0, "msg": "修改成功"}
        return http.HttpResponse(json.dumps(ret), content_type="application/json")


@method_decorator(csrf_exempt, name="dispatch")
class UserUploadView(LoginRequiredMixin, View):
    def post(self, request):
        avatar = request.FILES.get("file")
        print(avatar)
        image_data = avatar.read()
        # print(type(image_data))
        file_name = storage(image_data)
        # 将七牛云返回的图片名字拼接成url存储到数据库
        new_image_url = "http://images.zyntt.cn" + "/" + file_name
        try:
            user = request.user
            mobile = user.mobile
            users = User.objects.get(mobile=mobile)
            print(users.images_url)
            users.images_url = new_image_url
            users.save()
        except Exception as e:
            return http.JsonResponse({'code': 100, 'errmsg': '设置地址标题失败'})
        ret = {"status": 0, "msg": "修改成功"}
        return http.HttpResponse(json.dumps(ret), content_type="application/json")
        # response = redirect(reverse('user:upload'))
        # return response


class HomeView(View):
    def get(self, request):
        user_id = request.GET.get('u')
        print(user_id)
        users = User.objects.get(id=user_id)
        time = users.date_joined
        times = str(time)[0:10]
        fan = Fans.objects.filter(users=request.user.id)  # 登录的用户
        user12 = User.objects.get(id=user_id)
        print(user12.id, "1252")
        fans_m = Fans.objects.filter(users=user12.id, is_deleted=False)  # 主页 关注的用户
        print(fans_m)
        fan_m = Fans.objects.filter(parentss=user12.id, is_deleted=False)  # 主页 关注他的用户
        print(len(fans_m))
        print(len(fan_m))

        try:
            fan = Fans.objects.filter(users=request.user.id, parentss=user_id, is_deleted=False)  # 登录的用户
            if fan:
                fan_t = "2020"
            else:
                fan_t = "2018"
        except Fans.DoesNotExist:
            fan_t = "2018"
        user = User.objects.get(id=user_id)
        category = Category.objects.get(id=1)
        news = News.objects.filter(user=user, category=category)
        case = Case.objects.filter(user=user)
        print(fan_t, "*" * 20)
        context = {
            'case': case,
            'news': news,
            'users': users,
            'user': request.user,
            "time": times,
            "fans_m": len(fans_m),
            "fan_m": len(fan_m),
            "fan_t": fan_t,

        }
        return render(request, "user/home.html", context=context)


@method_decorator(csrf_exempt, name="dispatch")
class HomesView(LoginRequiredMixin, View):
    def post(self, request):
        user = request.user
        data = json.loads(request.body)
        # gz: "do"
        # user_id: 2
        gz = data.get("gz")
        user_id = data.get("user_id")
        users = User.objects.get(id=user_id)
        if gz == "do":
            try:
                try:
                    user = Fans.objects.get(parentss=users, users=user)
                    user.is_deleted = False
                    user.save()
                except Fans.DoesNotExist:
                    user = Fans.objects.create(parentss=users, users=user, is_deleted=False)
            except DatabaseError:
                response = redirect(reverse('user:home'))
                return response
            ret = {
                "errno": 0,
                "errmsg": "关注成功"
            }
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        elif gz == "undo":
            """取消关注"""

            try:
                # 查询要删除的关注
                user = Fans.objects.get(parent_id=user_id, user=user.id, is_deleted=False)
                # 将地址逻辑删除设置为True
                user.is_deleted = True
                user.save()
            except Fans.DoesNotExist:
                response = redirect(reverse('user:home'))
                return response
            ret = {
                "errno": 0,
                "errmsg": "关注成功"
            }
            return http.HttpResponse(json.dumps(ret), content_type="application/json")

        else:
            response = redirect(reverse('user:home'))
            return response


class VerifyEmailView(View):
    """验证邮箱"""

    def get(self, request):
        """实现邮箱验证逻辑"""
        # 接收参数
        token = request.GET.get('token')

        # 校验参数：判断token是否为空和过期，提取user
        if not token:
            return http.HttpResponseBadRequest('缺少token')

        # 验证邮箱url是否有效
        user = Email.verify_email(token)
        if not user:
            return http.HttpResponseBadRequest('无效的token')

        # 修改email_active的值为True
        try:
            user.email_active = '0'
            user.save()
        except Exception as e:
            return http.HttpResponseServerError('激活邮件失败')

        # 返回邮箱验证结果
        return redirect(reverse('user:userindex'))


class CollectsView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user
        try:
            collections = Collection.objects.filter(user=user.id, is_deleted=False)
            # print(collections)
        except Exception as e:
            response = redirect(reverse('index:index'))
            return response
        collections_list = []
        for i in collections:
            news = News.objects.get(id=i.news)
            print(news.title)
            collections_list.append(
                {
                    "title": news.title,
                    "id": i.news,
                    "time": i.create_time
                }
            )

        context = {

            'user': request.user,
            'collections': collections_list,
            "num": len(collections)

        }
        return render(request, "user/collect.html", context=context)


class MessageView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user
        news = News.objects.filter(user=user).order_by("-create_time")
        # 创建分页器：每页N条记录
        paginator = Paginator(news, 10)
        # 获取每页商品数据
        try:
            page_nums = request.GET.get("page")
            print(page_nums)
            page_num = int(page_nums)
        except:
            page_num = 1
        try:
            page_skus = paginator.page(page_num)
            print(page_skus)
        except EmptyPage:
            # 如果page_num不正确，默认给用户404
            return http.HttpResponseNotFound('empty page')
        # 获取列表页总页数
        total_page = paginator.num_pages
        # print(news)
        user = request.user
        if str(user) == "AnonymousUser":
            context = {
                'num': 1,
                'page_skus': page_skus,  # 分页后数据
                'total_page': total_page,  # 总页数
                'page_num': page_num,  # 当前页码
            }
        else:
            context = {
                'num': 1,
                'nums': len(page_skus),
                'user': user,
                'page_skus': page_skus,  # 分页后数据
                'total_page': total_page,  # 总页数
                'page_num': page_num,  # 当前页码
            }

        return render(request, 'user/content.html', context=context)


class FlyView(View):
    """用户注册"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """
        user = request.user
        context = {
            'user': user
        }
        return render(request, 'user/fly_kiss.html', context=context)


@method_decorator(csrf_exempt, name="dispatch")
class FollowView(View):
    """用户关注"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """
        user = request.user
        follo = Fans.objects.filter(users=user, is_deleted=False)

        context = {
            'follow': follo,
            'user': user
        }
        return render(request, 'user/follow.html', context=context)

    def post(self, request):
        user = request.user
        data = json.loads(request.body.decode("utf-8"))
        follow_id = data.get("follow_id")
        print(follow_id)
        if not all([user, follow_id]):
            ret = {"status": 201, "msg": "缺少参数"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        try:
            follow = Fans.objects.get(users=user, is_deleted=False, id=follow_id)
            follow.is_deleted = True
            follow.save()
        except Fans.DoesNotExist:
            ret = {"status": 202, "msg": "你没有关注"}
            return http.HttpResponse(json.dumps(ret), content_type="application/json")
        ret = {"status": 0, "msg": "取消关注成功"}
        return http.HttpResponse(json.dumps(ret), content_type="application/json")
